/* 
 * Copyright [2018] [Alex/libo(liboms@hotmail.com)]
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.apidoc.parser;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import com.hyts.apidoc.analysis.AnalysisEngine;
import com.hyts.apidoc.base.BaseApiParser;
import com.hyts.apidoc.bean.ScanBaseObject;
import com.hyts.apidoc.javadoc.JavaDocSupport;
import com.hyts.apidoc.model.ApiDefination;
import com.hyts.apidoc.model.ApiDoc;
import com.hyts.apidoc.model.ApiParam;
import com.hyts.apidoc.scanner.SourceScanner;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.Parameter;

/**
 * @title JavaDocApiParser.java
 * @package com.hyts.apidoc.parser
 * @description JavaDoc操作处理生成的class信息
 * @author libo/Alex
 * @email liboms@hotmail.com/liboware@163.com
 * @date 2018年4月23日
 * @version V1.0
 */
public class JavaDocApiParser implements BaseApiParser<ClassDoc[], ApiDoc> {

    static List<ApiDoc> apiDocList = new LinkedList<>();

    /*
     * (非 Javadoc) <b>实现方法- generateDoc </b> <p>generateDoc</p>
     * 
     * @param param ClassDoc文档集合
     * 
     * @return
     * 
     * @see com.hyts.apidoc.base.BaseApiParser#generateDoc(java.lang.Object)
     * 
     * @exception
     */
    @Override
    public List<ApiDoc> generateDoc(ClassDoc[] param) {
        // List<ApiDoc> apiDocs = new LinkedList<ApiDoc>();
        for (ClassDoc doc : param) {
            // 操作对应的type级别的javadoc注释
            ApiDoc apiDoc = AnalysisEngine.analysisTypeHeader(doc.tags());
            if (StringUtils.isEmpty(apiDoc.getPackageName())) {
                apiDoc.setPackageName(StringUtils.replace(doc.qualifiedName(), "." + doc.name(), ""));
            }
            if (StringUtils.isEmpty(apiDoc.getApiTypeName())) {
                apiDoc.setApiTypeName(doc.name());
            }
            for (MethodDoc methodDoc : doc.methods()) {
                System.out.println("------method---"+methodDoc.name());
                apiDoc = AnalysisEngine.analysisMethodHeader(methodDoc, apiDoc, methodDoc.tags());
                List<ApiDefination> methodData = apiDoc.getApiDefinationList();
                for (ApiDefination methodDataO : methodData) {
                    methodDataO.setPackageName(methodDoc.containingPackage().name());
                    methodDataO.setName(methodDoc.name());
                    if (CollectionUtils.isEmpty(methodDataO.getInputParameters())) {
                        List<ApiParam> inputParameters = null;
                        inputParameters = new LinkedList<>();
                        for (Parameter paramSubject : methodDoc.parameters()) {
                            ApiParam paramS = new ApiParam();
                            paramS.setIsRequired("是");
                            paramS.setParamName(paramSubject.name());
                            paramS.setParamType(paramSubject.typeName());
                            paramS.setParamDescription(paramSubject.typeName()+":"+paramSubject.name());
                            inputParameters.add(paramS);
                        }
                        methodDataO.setInputParameters(inputParameters);
                    }
                    if(CollectionUtils.isEmpty(methodDataO.getOutputParameters())){
                        ApiParam paramS = new ApiParam();
                        List<ApiParam> outParameters = new LinkedList<>();
                        paramS.setIsRequired("");
                        paramS.setParamName(methodDoc.qualifiedName());
                        paramS.setParamType(methodDoc.returnType().simpleTypeName());
                        paramS.setParamDescription(methodDoc.modifiers()+":"+methodDoc.qualifiedName()+":"+methodDoc.returnType().simpleTypeName());
                        outParameters.add(paramS);
                        methodDataO.setOutputParameters(outParameters);
                    }
                }
            }
            apiDocList.add(apiDoc);
        }
        return apiDocList;
    }

    /**
     * <b>执行解析文档生产文档操作</b> @param scanBaseObject @return @exception
     */
    public List<ApiDoc> execute(ScanBaseObject scanBaseObject) {
        JavaDocSupport.buildJavaDocParam(new SourceScanner(true).scan(scanBaseObject).scanResultFile);
        return apiDocList;
    }

    public static List<ApiDoc> getApiDocList() {
        return apiDocList;
    }

}
